package com.ruoyi.project.system.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IdUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.WeekTranUtils;
import com.ruoyi.project.system.domain.TRecruitPersonExamine;
import com.ruoyi.project.system.domain.TRecruitPersonInfo;
import com.ruoyi.project.system.domain.TRecruitPersonResume;
import com.ruoyi.project.system.domain.vo.RecruitPersonVo;
import com.ruoyi.project.system.mapper.TRecruitPersonExamineMapper;
import com.ruoyi.project.system.mapper.TRecruitPersonInfoMapper;
import com.ruoyi.project.system.mapper.TRecruitPersonResumeMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.mapper.TRecruitPersonMapper;
import com.ruoyi.project.system.domain.TRecruitPerson;
import com.ruoyi.project.system.service.ITRecruitPersonService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;
import static org.apache.poi.ss.usermodel.CellType.*;

/**
 * 义工信息Service业务层处理
 *
 * @author tianchao
 * @date 2021-09-05
 */
@Service
@Slf4j
public class TRecruitPersonServiceImpl extends ServiceImpl<TRecruitPersonMapper, TRecruitPerson> implements ITRecruitPersonService {
    @Resource
    private TRecruitPersonMapper tRecruitPersonMapper;

    @Resource
    private TRecruitPersonResumeMapper tRecruitPersonResumeMapper;

    @Resource
    private TRecruitPersonExamineMapper recruitPersonExamineMapper;

    @Resource
    private TRecruitPersonInfoMapper recruitPersonInfoMapper;


    /**
     * 查询义工信息
     *
     * @param id 义工信息主键
     * @return 义工信息
     */
    @Override
    public RecruitPersonVo selectTRecruitPersonById(String id) {

        RecruitPersonVo personVo = new RecruitPersonVo();

        //查询义工的基本信息
        TRecruitPerson tRecruitPerson = tRecruitPersonMapper.selectById(id);
        //查询义工的简历信息
        List<TRecruitPersonResume> tRecruitPersonResumes = tRecruitPersonResumeMapper
                .selectList(new LambdaQueryWrapper<TRecruitPersonResume>()
                        .eq(TRecruitPersonResume::getPersonId, id));
        BeanUtils.copyProperties(tRecruitPerson, personVo);

        //设置简历
        personVo.setResumeList(tRecruitPersonResumes);

        return personVo;
    }

    /**
     * 查询义工信息列表
     *
     * @param tRecruitPerson 义工信息
     * @return 义工信息
     */
    @Override
    public List<TRecruitPerson> selectTRecruitPersonList(TRecruitPerson tRecruitPerson) {
        return tRecruitPersonMapper.selectTRecruitPersonList(tRecruitPerson);
    }

    /**
     * 查询义工信息列表
     *
     * @param tRecruitPerson 义工信息
     * @return 义工信息
     */
    @Override
    public List<TRecruitPerson> listForSelect(TRecruitPerson tRecruitPerson) {
        //TODO 后期加上状态判断，更方便查找
        return tRecruitPersonMapper.selectList(new LambdaQueryWrapper<TRecruitPerson>()
                .like(StringUtils.isNotBlank(tRecruitPerson.getName()), TRecruitPerson::getName, tRecruitPerson.getName()));
    }

    /**
     * 新增义工信息
     *
     * @param tRecruitPerson 义工信息
     * @return 结果
     */
    @Override
    public int insertTRecruitPerson(TRecruitPerson tRecruitPerson) {
        tRecruitPerson.setCreateTime(DateUtils.getNowDate());
        return tRecruitPersonMapper.insert(tRecruitPerson);
    }

    /**
     * 修改义工信息
     *
     * @param tRecruitPerson 义工信息
     * @return 结果
     */
    @Override
    public int updateTRecruitPerson(TRecruitPerson tRecruitPerson) {
        tRecruitPerson.setUpdateTime(DateUtils.getNowDate());
        return tRecruitPersonMapper.updateById(tRecruitPerson);
    }

    /**
     * 批量删除义工信息
     *
     * @param ids 需要删除的义工信息主键
     * @return 结果
     */
    @Override
    public int deleteTRecruitPersonByIds(String[] ids) {
        return tRecruitPersonMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除义工信息信息
     *
     * @param id 义工信息主键
     * @return 结果
     */
    @Override
    public int deleteTRecruitPersonById(String id) {
        return tRecruitPersonMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> parseExcel(MultipartFile file) {


        Map<String, Object> resultMap = new HashMap<>();


        List<Map<String, Object>> resultList = new ArrayList<>();

        //获取文件名称
        InputStream in = null;
        try {
            String name = file.getOriginalFilename();
            //获取周几的日期
            String day = name.substring(name.indexOf("周") + 1, name.indexOf("周") + 2);
            in = file.getInputStream();

            // 读取整个Excel
            Workbook sheets = WorkbookFactory.create(in);
            // 获取第一个表单Sheet

            for (int sheetIndex = 0; sheetIndex <= 1; sheetIndex++) {
                /**
                 * 是否需要结束
                 */
                boolean isNeedEnd = false;
                Sheet sheetAt = sheets.getSheetAt(sheetIndex);
                ArrayList<Map<String, Object>> list = new ArrayList<>();
                // 读取每一格内容
                Map<String, Object> resultItem = null;
                for (int cellIndex = 3; cellIndex < sheetAt.getPhysicalNumberOfRows(); cellIndex++) {

                    resultItem = new HashMap<>();

                    Map<String, Object> baseInfo = new HashMap<>();
                    baseInfo.put("day", day);
                    //第一页是 上午 第二页是 下午
                    baseInfo.put("time", sheetIndex == 0 ? 1 : 2);

                    Map<String, Object> examine = new HashMap<>();
                    Row row = sheetAt.getRow(cellIndex);
//                    log.info("开始第:{}行", cellIndex);

                    for (int index = 0; index < 25; index++) {
                        String s = checkValue(sheetIndex, index, row);
//                        log.info("接收到的数据:{},第{}格", s, index);
                        //如果第一行读取出来没数据，那就不继续读取了
                        if (index == 0) {
                            if (StringUtils.isBlank(s)) {
                                isNeedEnd = true;
//                                log.info("-结束循环！！！！！{},{}-",s,index+1);
                                break;
                            }
                        }
                        //开始获取基础数据,0到第九格是基础数据
                        if (index >= 0 && index <= 9) {
                            baseInfo.put(String.valueOf(index + 1), s);
                        }
                        if (index >= 22 && index <= 24) {
                            baseInfo.put(String.valueOf(index + 1), s);
                        }
                        //10到17行是见习记录
                        if (index >= 10 && index <= 16) {
                            examine.put(String.valueOf(index + 1), s);
                        }
                        //17到19是 见习时间 圆满时间 上报时间
                        if (index >= 17 && index <= 19) {
                            baseInfo.put(String.valueOf(index + 1), s);
                        }
                    }

                    resultItem.put("baseInfo", baseInfo);
                    resultItem.put("examine", examine);
                    resultList.add(resultItem);
                    if (isNeedEnd) {
                        break;
                    }
                }
            }
            this.insertDataInfo(resultList);
            resultMap.put("status", 200);
            resultMap.put("msg", "成功导入" + resultList.size() + "条数据");
        } catch (IOException e) {
            e.printStackTrace();
            resultMap.put("status", 500);
            resultMap.put("msg", "导入失败，原因:" + e.getMessage());
        }
        return resultMap;
    }


    private void insertDataInfo(List<Map<String, Object>> resultList) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        log.info("导入的数据{}", resultList);

        Map<String, Object> result = new HashMap<>();

        resultList.forEach(i -> {
            try {
                Map baseInfo = (Map) i.get("baseInfo");
                Map examine = (Map) i.get("examine");

                if (baseInfo.get("1") == null) {
                    return;
                }
                Date enrollDate = sdf.parse(baseInfo.get("1").toString());
                String idCard = baseInfo.get("6").toString();
                TRecruitPerson tRecruitPerson = tRecruitPersonMapper.selectOne(new LambdaQueryWrapper<TRecruitPerson>().eq(TRecruitPerson::getIdCard, idCard));
                String personId = "";
                if (tRecruitPerson == null) {
                    //如果为空，
                    TRecruitPerson tbPerson = new TRecruitPerson();
                    String newPersonId = IdUtils.fastSimpleUUID();
                    personId = newPersonId;
                    tbPerson.setId(newPersonId);
                    //设置姓名
                    tbPerson.setName(baseInfo.get("3").toString().replaceAll(" ", ""));
                    tbPerson.setSex(baseInfo.get("4").toString().equals("男") ? 0l : 1l);
                    tbPerson.setPhone(baseInfo.get("5").toString());
                    tbPerson.setIdCard(baseInfo.get("6").toString());
                    tbPerson.setNativePlace(baseInfo.get("7").toString());
//                    tbPerson.setNativePlace(baseInfo.get("8").toString());
                    tbPerson.setProfessionalCertificate(baseInfo.get("9").toString());
                    tbPerson.setOccupation(baseInfo.get("10").toString());
                    tbPerson.setServiceTime(Long.parseLong(baseInfo.get("time").toString()));
                    tbPerson.setServiceWeek(WeekTranUtils.weekForNum(baseInfo.getOrDefault("day", "").toString()));
                    tbPerson.setCreateTime(new Date());
                    tbPerson.setCreateBy(getLoginUser().getUsername());
                    tbPerson.setRemark(baseInfo.get("25").toString());
                    tRecruitPersonMapper.insert(tbPerson);
                } else {
                    personId = tRecruitPerson.getId();
                }
                //插入扩展信息表,如果接收时间不为空，那么才插入
                String source = baseInfo.getOrDefault("24","").toString();
                String endDate = baseInfo.getOrDefault("19","").toString();
                String startDate = baseInfo.getOrDefault("18","").toString();

                TRecruitPersonInfo tRecruitPersonInfo = recruitPersonInfoMapper.selectOne(new LambdaQueryWrapper<TRecruitPersonInfo>()
                        .eq(TRecruitPersonInfo::getPersonId, personId));

                if (tRecruitPersonInfo == null) {
                    tRecruitPersonInfo = new TRecruitPersonInfo();
                    tRecruitPersonInfo.setId(IdUtils.fastSimpleUUID());
                    tRecruitPersonInfo.setPersonId(personId);
                    tRecruitPersonInfo.setCreateTime(new Date());
                    tRecruitPersonInfo.setCreateBy(getLoginUser().getUsername());
                    extracted(sdf, baseInfo, enrollDate, source, endDate, startDate, tRecruitPersonInfo);
                    recruitPersonInfoMapper.insert(tRecruitPersonInfo);
                } else {
                    extracted(sdf, baseInfo, enrollDate, source, endDate, startDate, tRecruitPersonInfo);
                    tRecruitPersonInfo.setUpdateBy(getLoginUser().getUsername());
                    tRecruitPersonInfo.setUpdateTime(new Date());
                }
                recruitPersonInfoMapper.updateById(tRecruitPersonInfo);


                //插入见习记录
                if (examine != null) {
                    //导览组	接待组	菩提组	金刚组	社工	礼仪培训	法会/花果/慈善
                    // 11=2021-05-09, 12=2021-06-13, 13=2021-07-03, 14=2021-06-20, 15=2021-06-19, 16=2021-05-30, 17=2021/6/29(法会)

                    for (int j = 11; j <= 17; j++) {

                        Object item = examine.get(String.valueOf(j));
                        if (item != null && (StringUtils.isNotBlank(item.toString()))) {
                            Long groupId = new Long(j - 10);
                            Date date;
                            //17 需要单独处理
                            if (j == 17) {
                                String s = item.toString();
                                log.info("======={}", s);
                                groupId = getOtherGroupId(s);
                                date = getOtherDate(s);
                            } else {
                                date = sdf.parse(item.toString());
                            }
                            //如果已经存在，那么不插入
                            Integer integer = recruitPersonExamineMapper.selectCount(new LambdaQueryWrapper<TRecruitPersonExamine>()
                                    .eq(TRecruitPersonExamine::getPersonId, personId)
                                    .eq(TRecruitPersonExamine::getGroupId, groupId));
                            if (integer > 0) {
                                return;
                            }
                            TRecruitPersonExamine tRecruitPersonExamine = new TRecruitPersonExamine();
                            tRecruitPersonExamine.setPersonId(personId);
                            tRecruitPersonExamine.setExamineDate(date);
                            tRecruitPersonExamine.setGroupId(groupId);
                            //默认合格
                            tRecruitPersonExamine.setIsOk(1);
                            tRecruitPersonExamine.setCreateTime(new Date());
                            tRecruitPersonExamine.setCreateBy(getLoginUser().getUsername());
                            recruitPersonExamineMapper.insert(tRecruitPersonExamine);
                        }
                    }
                }
            } catch (Exception e) {
                result.put("status", 500);
                result.put("msg", "解析有误");
                log.error("解析出错", e);
            }
        });
    }

    private void extracted(SimpleDateFormat sdf, Map baseInfo, Date enrollDate, String source, String endDate, String startDate, TRecruitPersonInfo tRecruitPersonInfo) throws ParseException {
        tRecruitPersonInfo.setEnrollDate(enrollDate);
        tRecruitPersonInfo.setPurposeReceiverName(baseInfo.get("23").toString());
        if (StringUtils.isNotBlank(source)){
            tRecruitPersonInfo.setPurposeReceiverTime(sdf.parse(source));
        }
        if (StringUtils.isNotBlank(endDate)){
            tRecruitPersonInfo.setProbationEndDate(sdf.parse(endDate));
        }
        if (StringUtils.isNotBlank(startDate)){
            tRecruitPersonInfo.setProbationStartDate(sdf.parse(startDate));
        }

    }

    /**
     * 把单元格的内容转为字符串
     *
     * @param xssfCell 单元格
     * @return String
     */
    public static String getString(XSSFCell xssfCell) {
        if (xssfCell == null) {
            return "";
        }
        if (xssfCell.getCellTypeEnum() == NUMERIC) {
            return String.valueOf(xssfCell.getNumericCellValue());
        } else if (xssfCell.getCellTypeEnum() == BOOLEAN) {
            return String.valueOf(xssfCell.getBooleanCellValue());
        } else {
            return xssfCell.getStringCellValue();
        }
    }

    public static String checkValue(int i, int j, Row row) {
        Cell cell = row.getCell(j);
        String value = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (cell == null) {
            cell = row.createCell(0);
            cell.setCellValue("");
        }
        try {
            CellType cellType = cell.getCellType();
            switch (cellType) {
                case STRING:
                    value = cell.getStringCellValue().trim();
                    break;
                case BOOLEAN:
                    value = String.valueOf(cell.getBooleanCellValue());
                    break;
                case FORMULA:
                    //处理数字和公式
                    value = String.valueOf(Double.valueOf(cell.getNumericCellValue()));
                    value = value.replaceAll("0+?$", "");
                    value = value.replaceAll("[.]$", "");
                    break;
                case NUMERIC:
                    //处理日期格式的Excel数据
                    if (DateUtil.isCellDateFormatted(cell)) {
                        Date date = cell.getDateCellValue();
                        value = sdf.format(date);
                    } else {
                        //处理科学计数法
                        double temp = cell.getNumericCellValue();
                        DecimalFormat df = new DecimalFormat("0");
                        value = df.format(temp);
                    }
                    break;
                default:
                    return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导入失败!第" + (i + 1) + "行第" + (j + 1) + "列,格式有误\n");
        }
        return value;
    }

    public static void main(String[] args) throws ParseException {
        String s = "2021/6/29（法会)";
        System.out.println(getOtherDate(s));
        System.out.println(getOtherGroupId(s));

    }


    public static Long getOtherGroupId(String s) {
        String newString = trans(s);

        String substring = newString.substring(newString.indexOf("(") + 1, newString.indexOf(")"));
        long groupId = 0;
        if (substring.equals("法会")) {
            groupId = 7;
        }
        if (substring.equals("花果")) {
            groupId = 8;
        }
        if (substring.equals("慈善")) {
            groupId = 9;
        }
        return groupId;
    }

    public static Date getOtherDate(String s) throws ParseException {
        String newString = trans(s);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

        String substring = newString.substring(0, newString.indexOf("("));
        return sdf.parse(substring);
    }


    static String trans(String Node) {
        String newNode = null;
        String allConvertNode = null;
        if (Node.contains("（") && Node.contains("）")) {
            newNode = Node.replaceAll("（", "(");
            allConvertNode = newNode.replace("）", ")");
        } else if (!(Node.contains("（")) && Node.contains("）")) {
            allConvertNode = Node.replaceAll("）", ")");
        } else if (Node.contains("（") && !(Node.contains("）"))) {
            newNode = Node.replaceAll("（", "(");
            allConvertNode = newNode;
        } else {
            allConvertNode = Node;
        }
        return allConvertNode;
    }
}
